#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stdexcept>
using namespace std;

class Array {
private:
	size_t i_size;
	int * i_data;
	size_t i_count;
public:
	explicit Array(const size_t size) : i_size(size), i_count(size) {
		i_data = new int[i_size];
		memset (i_data, 0, (i_size)*sizeof(int));
	}

	Array(const Array &arr) {
		i_size = arr.i_size;
		i_data = new int[i_size];
		memcpy (i_data, arr.i_data, (i_size)*sizeof(int));
		i_count = arr.i_count;
	}

	~Array() {
		delete[] i_data;
	}

	
	Array & operator = (Array& arr) {
		if(this == &arr) {
			return arr;
		}
		delete[] i_data;
		i_size = arr.i_size;
		i_data = new int[i_size];
		memcpy (i_data, arr.i_data, (i_size)*sizeof(int));
		i_count = arr.i_count;
		return *this;
	}

		
	int & operator[](const size_t index) {
		if(index < i_size) {
			i_count = index > i_count? index: i_count; 
			return i_data[index];
		} else {
			throw std::out_of_range ("Out of range");
		}
	}

	const int & operator[](const size_t index) const {
		if(index < i_size) {
			return i_data[index];
		} else {
			throw std::out_of_range ("Out of range");
		}
	}


	int get (const size_t index) {
		if(index < i_size) {
			return i_data[index];
		} else {
			throw std::out_of_range ("Out of range");
		}
	}

	int size () {
		return i_size;
	}

	int count () {
		return i_count;
	}


	void set (const size_t index, const int value) {
		if(index < i_size) {
			i_data[index] = value;
			i_count = index > i_count? index: i_count; 
		} else {
			throw std::out_of_range ("Out of range");
		}
	}

	void add(const int value) {
		if(i_count >= i_size) {
			int * temp;
			temp = i_data;
			i_data = new int[i_size * 2];
			memcpy (i_data, temp, (i_size)*sizeof(int));
			delete[] temp;
			i_size *= 2;
			i_count = i_count;
		}
		
		i_data[i_count++] = value;
	}

	friend ostream &operator<<(ostream &out, Array & arr){
		out<<"Size: " << arr.i_size <<", Count: " << arr.i_count << ", Elements: \n";
		for(size_t i = 0; arr.i_count > 0 && i < arr.i_count - 1; i++) {
			out << arr.i_data[i] << ",";
		}
		if(arr.i_count >= 1) {
			out << arr.i_data[arr.i_count - 1] << "\n";
		}
        return out;
	}

};




